Node.js RESTful API

REST স্থাপত্য শৈলী ব্যবহার করে দক্ষ এবং মাপযোগ্য ওয়েব পরিষেবাগুলি তৈরি করতে শিখুন৷

RESTful API বোঝা

REST (রিপ্রেজেন্টেশনাল স্টেট ট্রান্সফার) হল নেটওয়ার্ক অ্যাপ্লিকেশন ডিজাইন করার জন্য একটি স্থাপত্য শৈলী যা ওয়েব পরিষেবার জন্য আদর্শ হয়ে উঠেছে।

RESTful APIগুলি অ্যাপ্লিকেশনগুলিকে সংহত করার এবং বিভিন্ন সিস্টেমের মধ্যে যোগাযোগ সক্ষম করার জন্য একটি নমনীয়, হালকা উপায় প্রদান করে।

মূল ধারণা:

সম্পদ

সবকিছুই একটি সম্পদ (ব্যবহারকারী, পণ্য, অর্ডার)।

প্রতিনিধিত্ব

সম্পদের একাধিক উপস্থাপনা থাকতে পারে (JSON, XML, ইত্যাদি)

অস্থির

প্রতিটি অনুরোধে সমস্ত প্রয়োজনীয় তথ্য রয়েছে

ইন্টিগ্রেটেড ইন্টারফেস

সম্পদ অ্যাক্সেস এবং ম্যানিপুলেট করার একটি ধারাবাহিক উপায়

RESTful APIগুলি ইউআরএল হিসাবে উপস্থাপিত সংস্থানগুলিতে CRUD অপারেশন (তৈরি করুন, পড়ুন, আপডেট করুন, মুছুন) সঞ্চালনের জন্য HTTP অনুরোধগুলি ব্যবহার করে।

REST হল স্টেটলেস, যার মানে হল একটি ক্লায়েন্ট থেকে সার্ভারের প্রতিটি অনুরোধে অনুরোধটি বুঝতে এবং প্রক্রিয়া করার জন্য প্রয়োজনীয় সমস্ত তথ্য থাকতে হবে।

SOAP বা RPC এর বিপরীতে, REST একটি প্রোটোকল নয়, কিন্তু একটি স্ট্রাকচারাল স্টাইল যা বিদ্যমান ওয়েব স্ট্যান্ডার্ড যেমন HTTP, URI, JSON এবং XML ব্যবহার করে।

মূল REST নীতিগুলি

এই নীতিগুলি বোঝা কার্যকর RESTful API ডিজাইন করার জন্য গুরুত্বপূর্ণ।

তারা নিশ্চিত করে যে আপনার API স্কেলযোগ্য, রক্ষণাবেক্ষণযোগ্য এবং ব্যবহার করা সহজ।

অনুশীলনের মূল নীতিগুলি:

সম্পদ ভিত্তিক:ক্রিয়াকলাপের পরিবর্তে সংস্থানগুলিতে মনোনিবেশ করুন
উদ্বায়ী:প্রতিটি দাবি স্বাধীন এবং স্বয়ংসম্পূর্ণ
ক্যাশেযোগ্য:প্রতিক্রিয়া তাদের ক্যাশেবিলিটি সংজ্ঞায়িত করে
ইন্টিগ্রেটেড ইন্টারফেস:সামঞ্জস্যপূর্ণ সম্পদ সনাক্তকরণ এবং পরিচালনা
স্তর ব্যবস্থা:ক্লায়েন্টকে অন্তর্নিহিত আর্কিটেকচার সম্পর্কে জানার প্রয়োজন নেই

REST কাঠামোর মূল নীতিগুলির মধ্যে রয়েছে:

HTTP পদ্ধতি এবং তাদের ব্যবহার

RESTful APIগুলি রিসোর্সগুলিতে ক্রিয়াকলাপগুলি সম্পাদন করতে স্ট্যান্ডার্ড HTTP পদ্ধতিগুলি ব্যবহার করে৷

প্রতিটি পদ্ধতির নির্দিষ্ট শব্দার্থ আছে এবং যথাযথভাবে ব্যবহার করা উচিত।

🔄শক্তি রূপান্তর এবং সুরক্ষা:

  • নিরাপদ মোড:GET, HEAD, OPTIONS (সম্পদ পরিবর্তন করা উচিত নয়)
  • শক্তি রূপান্তর পদ্ধতি:পান, রাখুন, মুছুন (অনেক অভিন্ন অনুরোধ = একের মতো একই ফলাফল)
  • শক্তি রূপান্তর ছাড়া:পোস্ট, প্যাচ (একাধিক কলের সাথে বিভিন্ন প্রভাব থাকতে পারে)

সর্বদা আপনার কার্যকলাপের উদ্দেশ্য মাপসই সবচেয়ে নির্দিষ্ট পদ্ধতি ব্যবহার করুন.

পদ্ধতি কর্ম উদাহরণ
GET সম্পদ (গুলি) পুনরুদ্ধার করুন GET /api/users
POST একটি নতুন সম্পদ তৈরি করুন POST /api/users
PUT সম্পূর্ণরূপে একটি সম্পদ রিফ্রেশ PUT /api/users/123
PATCH আংশিকভাবে একটি সম্পদ আপডেট করুন PATCH /api/users/123
DELETE একটি সম্পদ মুছুন DELETE /api/users/123

উদাহরণ: বিভিন্ন HTTP পদ্ধতি ব্যবহার করা

const express = require('express');
const app = express();

// Middleware for parsing JSON
app.use(express.json());

let users = [
  { id: 1, name: 'John Doe', email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];

// GET - Retrieve all users
app.get('/api/users', (req, res) => {
  res.json(users);
});

// GET - Retrieve a specific user
app.get('/api/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });
  res.json(user);
});

// POST - Create a new user
app.post('/api/users', (req, res) => {
  const newUser = {
    id: users.length + 1,
    name: req.body.name,
    email: req.body.email
  };
  users.push(newUser);
  res.status(201).json(newUser);
});

// PUT - Update a user completely
app.put('/api/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });

  user.name = req.body.name;
  user.email = req.body.email;

  res.json(user);
});

// DELETE - Remove a user
app.delete('/api/users/:id', (req, res) => {
  const userIndex = users.findIndex(u => u.id === parseInt(req.params.id));
  if (userIndex === -1) return res.status(404).json({ message: 'User not found' });

  const deletedUser = users.splice(userIndex, 1);
  res.json(deletedUser[0]);
});

app.listen(8080, () => {
  console.log('REST API server running on port 8080');
});

RESTful API আর্কিটেকচার এবং ডিজাইন

একটি ভাল-ডিজাইন করা API সামঞ্জস্যপূর্ণ নিদর্শন অনুসরণ করে যা এটিকে স্বজ্ঞাত এবং ব্যবহার করা সহজ করে তোলে। ভাল API ডিজাইন বিকাশকারীর অভিজ্ঞতা এবং দীর্ঘমেয়াদী রক্ষণাবেক্ষণের জন্য গুরুত্বপূর্ণ।

নকশা বিবেচনা:

সম্পদের নামকরণ:বিশেষ্য ব্যবহার করুন, ক্রিয়াপদ নয় (যেমন, /ব্যবহারকারীরা নয় /getUsers)
বহুবচন:প্যাকেজগুলির জন্য বহুবচন ব্যবহার করুন (/users/123 নয় /user/123)
শ্রেণিবিন্যাস:সম্পর্ক দেখানোর জন্য নেস্ট রিসোর্স (/users/123/orders)
ফিল্টারিং/বাছাই:ঐচ্ছিক ফাংশনের জন্য ক্যোয়ারী প্যারামিটার ব্যবহার করুন
সংস্করণ কৌশল:শুরু থেকেই API সংস্করণের পরিকল্পনা করুন (যেমন, /v1/ব্যবহারকারী বনাম /v2/ব্যবহারকারী)

একটি সুগঠিত API এই নিয়মগুলি অনুসরণ করে:

উদাহরণ: সুগঠিত API রুট

// Good API structure
app.get('/api/products', getProducts);
app.get('/api/products/:id', getProductById);
app.get('/api/products/:id/reviews', getProductReviews);
app.get('/api/users/:userId/orders', getUserOrders);
app.post('/api/orders', createOrder);

// Filtering and pagination
app.get('/api/products?category=electronics&sort=price&limit=10&page=2');

Node.js এবং Express দিয়ে REST API তৈরি করা

Node.js with Express.js RESTful API .

নিম্নলিখিত বিভাগগুলি বাস্তবায়নের জন্য সর্বোত্তম অনুশীলন এবং বিন্যাস সংজ্ঞায়িত করে।

মূল উপাদান:

Express Router

রুট সংগঠিত করা

মিডলওয়্যার

ক্রস-কাটিং উদ্বেগ জন্য

কন্ট্রোলার

অনুরোধ যুক্তি পরিচালনা করতে

নমুনা

ডেটা অ্যাক্সেস এবং ব্যবসায়িক যুক্তির জন্য

সেবা

জটিল ব্যবসায়িক যুক্তির জন্য

Express.js Node.js REST API .

এখানে একটি মৌলিক প্রকল্প কাঠামো:

Project Structure
- app.js # Main application file
- routes/ # Route definitions
  - users.js
  - products.js
- controllers/ # Request handlers
  - userController.js
  - productController.js
- models/ # Data models
  - User.js
  - Product.js
- middleware/ # Custom middleware
  - auth.js
  - validation.js
- config/ # Configuration files
  - db.js
  - env.js
- utils/ # Utility functions
  - errorHandler.js

উদাহরণ: এক্সপ্রেস রাউটার সেট আপ করা

// routes/users.js
const express = require('express');
const router = express.Router();
const { getUsers, getUserById, createUser, updateUser, deleteUser } = require('../controllers/userController');

router.get('/', getUsers);
router.get('/:id', getUserById);
router.post('/', createUser);
router.put('/:id', updateUser);
router.delete('/:id', deleteUser);

module.exports = router;

// app.js
const express = require('express');
const app = express();
const userRoutes = require('./routes/users');

app.use(express.json());
app.use('/api/users', userRoutes);

app.listen(8080, () => {
  console.log('Server is running on port 8080');
});

কন্ট্রোলার এবং মডেল

রুট, কন্ট্রোলার এবং মডেলগুলির মধ্যে উদ্বেগের বিচ্ছেদ কোড সংগঠন এবং রক্ষণাবেক্ষণযোগ্যতা উন্নত করে:

উদাহরণ: কন্ট্রোলার বাস্তবায়ন

// controllers/userController.js
const User = require('../models/User');

const getUsers = async (req, res) => {
  try {
    const users = await User.findAll();
    res.status(200).json(users);
  } catch (error) {
    res.status(500).json({ message: 'Error retrieving users', error: error.message });
  }
};

const getUserById = async (req, res) => {
  try {
    const user = await User.findById(req.params.id);
    if (!user) {
      return res.status(404).json({ message: 'User not found' });
    }
    res.status(200).json(user);
  } catch (error) {
    res.status(500).json({ message: 'Error retrieving user', error: error.message });
  }
};

const createUser = async (req, res) => {
  try {
    const user = await User.create(req.body);
    res.status(201).json(user);
  } catch (error) {
    res.status(400).json({ message: 'Error creating user', error: error.message });
  }
};

module.exports = { getUsers, getUserById, createUser };

API সংস্করণ

সংস্করণ আপনাকে বিদ্যমান গ্রাহকদের না ভেঙে আপনার API তৈরি করতে দেয়।

সাধারণ পদ্ধতির মধ্যে রয়েছে:

URI পাথ সংস্করণ

/api/v1/users

ক্যোয়ারী প্যারামিটার

/api/users?version=1

কাস্টম হেডার

X-API-Version: 1

হেডার গ্রহণ করুন

Accept: application/vnd.myapi.v1+json

উদাহরণ: URI পাথ সংস্করণ

const express = require('express');
const app = express();

// Version 1 routes
const v1UserRoutes = require('./routes/v1/users');
app.use('/api/v1/users', v1UserRoutes);

// Version 2 routes with new features
const v2UserRoutes = require('./routes/v2/users');
app.use('/api/v2/users', v2UserRoutes);

app.listen(8080);

যাচাইয়ের জন্য অনুরোধ করুন

ডেটা অখণ্ডতা এবং নিরাপত্তা নিশ্চিত করতে সর্বদা আগত অনুরোধগুলি যাচাই করুন৷

Joi বা express-validator এর মত লাইব্রেরি সাহায্য করতে পারে:

উদাহরণ: জয়ের সাথে বৈধতার অনুরোধ করুন

const express = require('express');
const Joi = require('joi');
const app = express();

app.use(express.json());

// Validation schema
const userSchema = Joi.object({
  name: Joi.string().min(3).required(),
  email: Joi.string().email().required(),
  age: Joi.number().integer().min(18).max(120)
});

app.post('/api/users', (req, res) => {
  // Validate request body
  const { error } = userSchema.validate(req.body);
  if (error) {
    return res.status(400).json({ message: error.details[0].message });
  }

  // Process valid request
  // ...
  res.status(201).json({ message: 'User created successfully' });
});

app.listen(8080);

ত্রুটি হ্যান্ডলিং

API গ্রাহকদের স্পষ্ট প্রতিক্রিয়া প্রদান করতে সামঞ্জস্যপূর্ণ ত্রুটি হ্যান্ডলিং প্রয়োগ করুন:

উদাহরণ: কেন্দ্রীভূত ত্রুটি পরিচালনা

// utils/errorHandler.js
class AppError extends Error {
  constructor(statusCode, message) {
    super(message);
    this.statusCode = statusCode;
    this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
    this.isOperational = true;

    Error.captureStackTrace(this, this.constructor);
  }
}

module.exports = { AppError };

// middleware/errorMiddleware.js
const errorHandler = (err, req, res, next) => {
  err.statusCode = err.statusCode || 500;
  err.status = err.status || 'error';

  // Different error responses for development and production
  if (process.env.NODE_ENV === 'development') {
    res.status(err.statusCode).json({
      status: err.status,
      message: err.message,
      stack: err.stack,
      error: err
    });
  } else {
    // Production: don't leak error details
    if (err.isOperational) {
      res.status(err.statusCode).json({
        status: err.status,
        message: err.message
      });
    } else {
      // Programming or unknown errors
      console.error('ERROR 💥', err);
      res.status(500).json({
        status: 'error',
        message: 'Something went wrong'
      });
    }
  }
};

module.exports = { errorHandler };

// Usage in app.js
const { errorHandler } = require('./middleware/errorMiddleware');
const { AppError } = require('./utils/errorHandler');

// This route throws a custom error
app.get('/api/error-demo', (req, res, next) => {
  next(new AppError(404, 'Resource not found'));
});

// Error handling middleware (must be last)
app.use(errorHandler);

API ডকুমেন্টেশন

এপিআই গ্রহণের জন্য ভালো ডকুমেন্টেশন অপরিহার্য।

সোয়াগার/ওপেনএপিআই-এর মতো টুলগুলি স্বয়ংক্রিয়ভাবে কোড থেকে ডকুমেন্টেশন তৈরি করতে পারে:

উদাহরণ: Swagger ডকুমেন্টেশন

const express = require('express');
const swaggerJsDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');

const app = express();

// Swagger configuration
const swaggerOptions = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'User API',
      version: '1.0.0',
      description: 'A simple Express User API'
    },
    servers: [
      {
        url: 'http://localhost:8080',
        description: 'Development server'
      }
    ]
  },
  apis: ['./routes/*.js'] // Path to the API routes folders
};

const swaggerDocs = swaggerJsDoc(swaggerOptions);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs));

/**
* @swagger
* /api/users:
* get:
* summary: Returns a list of users
* description: Retrieve a list of all users
* responses:
* 200:
* description: A list of users
* content:
* application/json:
* schema:
* type: array
* items:
* type: object
* properties:
* id:
* type: integer
* name:
* type: string
* email:
* type: string
*/
app.get('/api/users', (req, res) => {
  // Handler implementation
});

app.listen(8080);

টেস্টিং API

পরীক্ষা API নির্ভরযোগ্যতার জন্য গুরুত্বপূর্ণ।

জেস্ট, মোচা বা সুপারটেস্টের মতো লাইব্রেরি ব্যবহার করুন:

উদাহরণ: জেস্ট এবং সুপারটেস্ট সহ API পরীক্ষা

// tests/users.test.js
const request = require('supertest');
const app = require('../app');

describe('User API', () => {
  describe('GET /api/users', () => {
    it('should return all users', async () => {
      const res = await request(app).get('/api/users');
      expect(res.statusCode).toBe(200);
      expect(Array.isArray(res.body)).toBeTruthy();
    });
  });
  describe('POST /api/users', () => {
    it('should create a new user', async () => {
      const userData = {
        name: 'Test User',
        email: 'test@example.com'
      };
      const res = await request(app)
        .post('/api/users')
        .send(userData);

      expect(res.statusCode).toBe(201);
      expect(res.body).toHaveProperty('id');
      expect(res.body.name).toBe(userData.name);
    });
    it('should validate request data', async () => {
      const invalidData = {
        email: 'not-an-email'
      };
      const res = await request(app)
        .post('/api/users')
        .send(invalidData);

      expect(res.statusCode).toBe(400);
    });
  });
});

সেরা অনুশীলনের সারসংক্ষেপ

REST নীতি অনুসরণ করুন এবং উপযুক্ত HTTP পদ্ধতি ব্যবহার করুন
শেষবিন্দুর জন্য ধারাবাহিক নামকরণের রীতি ব্যবহার করুন
রিসোর্স-ভিত্তিক ইউআরএলগুলির সাথে আপনার APIকে যৌক্তিকভাবে গঠন করুন
প্রতিক্রিয়াগুলিতে উপযুক্ত স্থিতি কোডগুলি ফেরত দিন
স্পষ্ট বার্তা সহ সঠিক ত্রুটি হ্যান্ডলিং বাস্তবায়ন
বড় ডেটা সেটের জন্য পেজিনেশন ব্যবহার করুন
পশ্চাদগামী সামঞ্জস্য বজায় রাখতে আপনার API সংস্করণ করুন
নিরাপত্তা সমস্যা প্রতিরোধ করতে সমস্ত ইনপুট যাচাই করুন
আপনার API পুঙ্খানুপুঙ্খভাবে নথিভুক্ত করুন
নির্ভরযোগ্যতা নিশ্চিত করতে বিস্তারিত পরীক্ষা লিখুন
সমস্ত উত্পাদন API-এর জন্য HTTPS ব্যবহার করুন
অপব্যবহার প্রতিরোধে হার নিয়ন্ত্রণ প্রয়োগ করুন

অনুশীলন করুন

সঠিক শব্দটি টেনে আনুন।

REST API এন্ডপয়েন্ট সাধারণত অপারেশন সংজ্ঞায়িত করতে HTTP ব্যবহার করে______ব্যবহার করছে

headers
✗ ভুল! এইচটিটিপি শিরোনামগুলি অপারেশনগুলিকে সংজ্ঞায়িত করার জন্য ব্যবহার করা হয় না, তবে অতিরিক্ত তথ্য প্রদানের জন্য
status codes
✗ ভুল! HTTP স্ট্যাটাস কোড একটি অনুরোধের সমাপ্তি নির্দেশ করে, কিন্তু অপারেশন সংজ্ঞায়িত করতে ব্যবহৃত হয় না
methods
✓ ঠিক আছে! REST API এন্ডপয়েন্ট সাধারণত HTTP পদ্ধতি যেমন GET, POST, PUT, DELETE, এবং PATCH ব্যবহার করে ক্রিয়াকলাপ সংজ্ঞায়িত করে
cookies
✗ ভুল! HTTP কুকিজ স্থিতি বজায় রাখতে ব্যবহার করা হয়, কিন্তু REST API অপারেশনগুলিকে সংজ্ঞায়িত করতে নয়